#include "bendilist.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 初始化班次链表
TrainList* initTrainList() 
{
    TrainList *list = (TrainList*)malloc(sizeof(TrainList));
    if (list) {
        list->head = NULL;
        list->count = 0;
    }
    return list;
}

// 解析座位信息
SeatInfo* parseSeatInfo(cJSON *seatArray, int *seatCount) 
{
    if (!seatArray || !cJSON_IsArray(seatArray)) {
        *seatCount = 0;
        return NULL;
    }
    
    int count = cJSON_GetArraySize(seatArray);
    if (count == 0) {
        *seatCount = 0;
        return NULL;
    }
    
    SeatInfo *seats = (SeatInfo*)malloc(count * sizeof(SeatInfo));
    if (!seats) {
        *seatCount = 0;
        return NULL;
    }
    
    for (int i = 0; i < count; i++) {
        cJSON *seatItem = cJSON_GetArrayItem(seatArray, i);
        if (seatItem) {
            // 解析座位价格
            cJSON *item = cJSON_GetObjectItem(seatItem, "SeatPrice");
            if (item) seats[i].SeatPrice = item->valuedouble;
            
            // 解析总座位数
            item = cJSON_GetObjectItem(seatItem, "TotalSeats");
            if (item) seats[i].TotalSeats = item->valueint;
            
            // 解析座位状态字符串
            item = cJSON_GetObjectItem(seatItem, "SeatStatus");
            if (item && item->valuestring) {
                seats[i].SeatStatus = strdup(item->valuestring);
            } else {
                seats[i].SeatStatus = NULL;
            }
            
            // 解析可用座位数
            item = cJSON_GetObjectItem(seatItem, "AvailableSeats");
            if (item) seats[i].AvailableSeats = item->valueint;
            
            // 解析座位号数组
            item = cJSON_GetObjectItem(seatItem, "SeatNumbers");
            if (item && cJSON_IsArray(item)) {
                int numCount = cJSON_GetArraySize(item);
                seats[i].SeatNumbers = (char**)malloc(numCount * sizeof(char*));
                
                for (int j = 0; j < numCount; j++) {
                    cJSON *numItem = cJSON_GetArrayItem(item, j);
                    if (numItem && numItem->valuestring) {
                        seats[i].SeatNumbers[j] = strdup(numItem->valuestring);
                    } else {
                        seats[i].SeatNumbers[j] = NULL;
                    }
                }
            } else {
                seats[i].SeatNumbers = NULL;
            }
        }
    }
    
    *seatCount = count;
    return seats;
}

// 将座位信息转换为JSON
cJSON* seatInfoToJSON(SeatInfo *seats, int seatCount) 
{
    cJSON *seatArray = cJSON_CreateArray();
    if (!seatArray) return NULL;
    
    for (int i = 0; i < seatCount; i++) {
        cJSON *seatObj = cJSON_CreateObject();
        if (!seatObj) continue;
        
        cJSON_AddNumberToObject(seatObj, "SeatPrice", seats[i].SeatPrice);
        cJSON_AddNumberToObject(seatObj, "TotalSeats", seats[i].TotalSeats);
        cJSON_AddStringToObject(seatObj, "SeatStatus", seats[i].SeatStatus);
        cJSON_AddNumberToObject(seatObj, "AvailableSeats", seats[i].AvailableSeats);
        
        // 添加座位号数组
        cJSON *numbersArray = cJSON_CreateArray();
        if (numbersArray && seats[i].SeatNumbers) {
            for (int j = 0; j < seats[i].TotalSeats; j++) {
                if (seats[i].SeatNumbers[j]) {
                    cJSON_AddItemToArray(numbersArray, cJSON_CreateString(seats[i].SeatNumbers[j]));
                }
            }
            cJSON_AddItemToObject(seatObj, "SeatNumbers", numbersArray);
        }
        
        cJSON_AddItemToArray(seatArray, seatObj);
    }
    
    return seatArray;
}

// 从JSON文件加载班次数据到链表
int loadTrainsFromFile(TrainList *list, const char *filename) 
{
    if (!list) return 0;
    
    FILE *file = fopen(filename, "r");
    if (!file) {
        printf("无法打开文件: %s\n", filename);
        return 0;
    }
    
    fseek(file, 0, SEEK_END);
    long length = ftell(file);
    fseek(file, 0, SEEK_SET);
    
    char *data = (char*)malloc(length + 1);
    if (!data) {
        fclose(file);
        return 0;
    }
    
    fread(data, 1, length, file);
    data[length] = '\0';
    fclose(file);
    
    cJSON *root = cJSON_Parse(data);
    free(data);
    
    if (!root) {
        printf("JSON解析失败\n");
        return 0;
    }
    
    cJSON *codeItem = cJSON_GetObjectItem(root, "code");
    if (!codeItem || codeItem->valueint != 200) {
        cJSON_Delete(root);
        return 0;
    }
    
    cJSON *dataArray = cJSON_GetObjectItem(root, "data");
    if (!dataArray || !cJSON_IsArray(dataArray)) {
        cJSON_Delete(root);
        return 0;
    }
    
    int trainCount = cJSON_GetArraySize(dataArray);
    for (int i = 0; i < trainCount; i++) {
        cJSON *trainItem = cJSON_GetArrayItem(dataArray, i);
        if (!trainItem) continue;
        
        Train *train = (Train*)malloc(sizeof(Train));
        if (!train) continue;
        
        // 解析班次基本信息
        cJSON *item = cJSON_GetObjectItem(trainItem, "TrainNumber");
        if (item) strncpy(train->TrainNumber, item->valuestring, sizeof(train->TrainNumber));
        
        item = cJSON_GetObjectItem(trainItem, "start");
        if (item) strncpy(train->start, item->valuestring, sizeof(train->start));
        
        item = cJSON_GetObjectItem(trainItem, "end");
        if (item) strncpy(train->end, item->valuestring, sizeof(train->end));
        
        item = cJSON_GetObjectItem(trainItem, "DepartTime");
        if (item) strncpy(train->DepartTime, item->valuestring, sizeof(train->DepartTime));
        
        item = cJSON_GetObjectItem(trainItem, "date");
        if (item) strncpy(train->date, item->valuestring, sizeof(train->date));
        
        item = cJSON_GetObjectItem(trainItem, "ArriveTime");
        if (item) strncpy(train->ArriveTime, item->valuestring, sizeof(train->ArriveTime));
        
        // 解析座位信息
        cJSON *seatsArray = cJSON_GetObjectItem(trainItem, "SeatList");
        train->seats = parseSeatInfo(seatsArray, &train->seatCount);
        
        train->next = NULL;
        
        // 添加到链表
        addTrain(list, train);
    }
    
    cJSON_Delete(root);
    return 1;
}

// 保存链表数据到JSON文件
int saveTrainsToFile(TrainList *list, const char *filename) 
{
    if (!list) return 0;
    
    cJSON *root = cJSON_CreateObject();
    if (!root) return 0;
    
    cJSON_AddNumberToObject(root, "code", 200);
    cJSON_AddStringToObject(root, "checkCode", "shiftManagement");
    
    cJSON *dataArray = cJSON_CreateArray();
    if (!dataArray) 
    {
        cJSON_Delete(root);
        return 0;
    }
    
    Train *current = list->head;
    while (current) 
    {
        cJSON *trainObj = cJSON_CreateObject();
        if (!trainObj) continue;
        
        cJSON_AddStringToObject(trainObj, "TrainNumber", current->TrainNumber);
        cJSON_AddStringToObject(trainObj, "start", current->start);
        cJSON_AddStringToObject(trainObj, "end", current->end);
        cJSON_AddStringToObject(trainObj, "DepartTime", current->DepartTime);
        cJSON_AddStringToObject(trainObj, "date", current->date);
        cJSON_AddStringToObject(trainObj, "ArriveTime", current->ArriveTime);
        
        cJSON *seatsArray = seatInfoToJSON(current->seats, current->seatCount);
        if (seatsArray) {
            cJSON_AddItemToObject(trainObj, "SeatList", seatsArray);
        }
        
        cJSON_AddItemToArray(dataArray, trainObj);
        current = current->next;
    }
    
    cJSON_AddItemToObject(root, "data", dataArray);
    
    char *jsonStr = cJSON_Print(root);
    cJSON_Delete(root);
    
    if (!jsonStr) return 0;
    
    FILE *file = fopen(filename, "w");
    if (!file) {
        free(jsonStr);
        return 0;
    }
    
    fputs(jsonStr, file);
    fclose(file);
    free(jsonStr);

    return 1;
}

// 添加班次到链表
void addTrain(TrainList *list, Train *train) 
{
    if (!list || !train) return;
    
    if (list->head == NULL) {
        list->head = train;
    } else {
        Train *current = list->head;
        while (current->next) {
            current = current->next;
        }
        current->next = train;
    }
    train->next = NULL;
    list->count++;
}

// 根据车次号查找班次
Train* findTrain(TrainList *list, const char *trainNumber) 
{
    if (!list || !trainNumber) return NULL;
    
    Train *current = list->head;
    while (current) {
        if (strcmp(current->TrainNumber, trainNumber) == 0) {
            return current;
        }
        current = current->next;
    }
    
    return NULL;
}

// 释放座位信息内存
void freeSeatInfo(SeatInfo *seats, int seatCount) 
{
    if (!seats) return;
    
    for (int i = 0; i < seatCount; i++)
    {
        if (seats[i].SeatStatus) free(seats[i].SeatStatus);
        
        if (seats[i].SeatNumbers) {
            for (int j = 0; j < seats[i].TotalSeats; j++) 
            {
                if (seats[i].SeatNumbers[j]) free(seats[i].SeatNumbers[j]);
            }
            free(seats[i].SeatNumbers);
        }
    }
    free(seats);
}

// 释放链表内存
void freeTrainList(TrainList *list) 
{
    if (!list) return;
    
    Train *current = list->head;
    while (current) {
        Train *next = current->next;
        freeSeatInfo(current->seats, current->seatCount);
        free(current);
        current = next;
    }
    
    free(list);
}

// 预订座位
int reserveSeat(Train *train, int seatType, int seatIndex) 
{
    if (!train || seatType < 0 || seatType >= train->seatCount || 
        seatIndex < 0 || seatIndex >= train->seats[seatType].TotalSeats) 
    {
        return 0;
    }
    
    if (train->seats[seatType].SeatStatus[seatIndex] == '1') 
    {
        train->seats[seatType].SeatStatus[seatIndex] = '0';
        train->seats[seatType].AvailableSeats--;
        return 1;
    }
    
    return 0;
}

// 释放座位
int freeSeat(Train *train, int seatType, int seatIndex) 
{
    if (!train || seatType < 0 || seatType >= train->seatCount || 
        seatIndex < 0 || seatIndex >= train->seats[seatType].TotalSeats) {
        return 0;
    }
    
    if (train->seats[seatType].SeatStatus[seatIndex] == '0') 
    {
        train->seats[seatType].SeatStatus[seatIndex] = '1';
        train->seats[seatType].AvailableSeats++;
        return 1;
    }
    
    return 0;
}

// 切换座位状态
int toggleSeatStatus(Train *train, int seatType, int seatIndex) 
{
    if (!train || seatType < 0 || seatType >= train->seatCount || 
        seatIndex < 0 || seatIndex >= train->seats[seatType].TotalSeats) 
        {
        return 0;
    }
    
    if (train->seats[seatType].SeatStatus[seatIndex] == '1')
     {
        return reserveSeat(train, seatType, seatIndex);
    } else {
        return freeSeat(train, seatType, seatIndex);
    }
}